﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FinanSoft.Entities;
using FinanSoft.DataLayer;
using FinanSoft.Utilities;

namespace FinanSoft.BusinessLayer.BuySaleStrategy
{
    public class ServiceDocManager
    {

        #region Atributos
        private bool _IsError;
        private String _ErrorMessage;
        #endregion

        #region Constructor
        public ServiceDocManager()
        {
            _IsError = false;
            _ErrorMessage = "";
        }
        #endregion

        #region Propiedades
        /// <summary>
        /// Devuelve si hubo o no un error
        /// </summary>
        public bool IsError
        {
            get { return _IsError; }
            set { _IsError = value; }
        }

        /// <summary>
        /// Devuelve el mensaje de error
        /// </summary>
        public String ErrorMessage
        {
            get { return _ErrorMessage; }
            set { _ErrorMessage = value; }
        }

        #endregion

        #region Métodos
        /// <summary>
        /// Método que se encarga de guardar un documento de tipo factura cliente o notas de crédito. Sirve
        /// específicamente para servicios.
        /// </summary>
        /// <param name="document">Documento que se va a guardar</param>
        /// <param name="docType">Tipo de documento FC o NC...</param>
        /// <returns>Retorna si hubo o no éxito en la operación</returns>
        public bool SaveDocument(Entities.Document document, Account salesAccount, string docType, Tax serviceTax, string description)
        {
            // Se obtiene el tipo de documento
            DocType type = DocumentTypeManager.GetInstance().GetType(docType);
            // Se intenta guardar en bd el encabezado del documento primero para que nos devuelva el id
            int docId = BuySaleDataManager.GetInstance().SaveDocumentHeader(document, type);
            if (docId == Constants.INVALID_ID)
            {
                _IsError = true;
                _ErrorMessage = Constants.ERROR_SAVING_DOC;
                return false;
            }
            document.idDocumento = docId;
            // Intentamos guardar los artículos para el documento que se insertó anteriormente
            string docCode = DocumentTypeManager.GetInstance().GetType(docType).CurrentNumber.ToString();
            AuxiliarAccount auxAccount = AuxiliaryAccountManager.GetInstance().GetAuxiliarAccount(document.IdCuentaAuxiliar);
            Currency docCurrency = MoneyManager.GetInstance().GetCurrency(document.IdMoneda);
            List<AccountingEntryDetail> invoiceDetails = new List<AccountingEntryDetail>();
            Constants.AccountingEntryType auxInc;
            Constants.AccountingEntryType otherInc;
            if (docType.Equals(Constants.NC_ACCOUNTING_ENTRY))
            {
                auxInc = Constants.AccountingEntryType.credit;
                otherInc = Constants.AccountingEntryType.debit;
            }
            else
            {
                auxInc = Constants.AccountingEntryType.debit;
                otherInc = Constants.AccountingEntryType.credit;
            }
            if (serviceTax != null)
            {
                // Hacemos el asiento para el impuesto de ventas
                double taxLocalAmount = Math.Round(document.subTotal * serviceTax.Porcentaje * docCurrency.ToLocalCurrency);
                double taxSystemAmount = Math.Round(taxLocalAmount / MoneyManager.GetInstance().SystemCurrency.ToLocalCurrency);
                int taxId = CatalogManager.GetInstance().GetAccountingCatalog().GetSpecialAccounts(Constants.SpecialType.salesTaxToPay)[0].AccountID;
                invoiceDetails.Add(AccountingEntryManager.GetInstance().BuildAccountingEntryDetail
                    (auxAccount.Parent, taxSystemAmount, taxLocalAmount, auxInc, auxAccount.AccountID));
                invoiceDetails.Add(AccountingEntryManager.GetInstance().BuildAccountingEntryDetail
                    (taxId, taxSystemAmount, taxLocalAmount, otherInc, Constants.INVALID_ID));
            }
            double serviceLocalAmount = Math.Round(document.subTotal * docCurrency.ToLocalCurrency);
            double serviceSystemAmount = Math.Round(serviceLocalAmount / MoneyManager.GetInstance().SystemCurrency.ToLocalCurrency);
            invoiceDetails.Add(AccountingEntryManager.GetInstance().BuildAccountingEntryDetail
                (auxAccount.Parent, serviceSystemAmount, serviceLocalAmount, auxInc, auxAccount.AccountID));
            invoiceDetails.Add(AccountingEntryManager.GetInstance().BuildAccountingEntryDetail
                (salesAccount.AccountID, serviceSystemAmount, serviceLocalAmount, otherInc, Constants.INVALID_ID));
            bool entryResult = AccountingEntryManager.GetInstance().CreateAndRecordAccountingEntry(
                docType, document.fechaVencimiento, document.fechaEmision, PeriodManager.GetInstance().GetCurrentAccountingPeriod().GetCurrentSeason().Id,
                "Código "+ docCode, "", "", invoiceDetails);
            if (!entryResult)
            {
                _IsError = true;
                _ErrorMessage = AccountingEntryManager.GetInstance().ErrorMessage;
                return false;
            }
            bool noErrorDB = BuySaleDataManager.GetInstance().SaveDocumentService(document, salesAccount, document.subTotal, description, serviceTax.IdImpuesto);
            if (!noErrorDB)
            {
                _IsError = true;
                _ErrorMessage = Constants.ERROR_SAVING_DOCS_SERVICES;
                return false;
            }
            DocumentTypeManager.GetInstance().IncreaseDocumentConsecutiveNumber(docType);
            return true;
        }

        public string GetErrorMessage()
        {
            return _ErrorMessage;
        }
        #endregion
    }
}
